/*
 * matrix.h
 *
 *  Created on: 04/06/2011
 *      Author: Yotam and Gilad
 */

#ifndef MATRIX_H_
#define MATRIX_H_

class Matrix {
	int numberOfRows;
	int numberOfColumns;
	double *data;

	//gets two indexes and checks whether they are valid
	void verifyIndex(int row, int col) const;
	//compares 2 or 4 dimensions
	static void compareDimensions(int a1, int a2, int b1 = 0, int b2 = 0);
	//allocates and copies a block of data of type double
	//returns a pointer to it
	static double* allocateAndCopy(const double* data, int size);
	//finds a leadind element in a matrix row
	const double& findLeadingElement(int row) const;
	void divideSubtractSwap(int row, int column, const double& scalar,
			Matrix& solutionMatrix);
	//swaps to rows in a matrix
	void swapRows(int row1, int row2);
	void devideRowByScalar(int row, const double& scalar);
	void subtractRows(int row1, int row2, const double& scalar);

public:
	Matrix(const int& rows, const int& cols);
	Matrix(const Matrix& matrix); // copy c'tor
	~Matrix();

	int columns() const;
	int rows() const;

	// c = m(1,2)
	const double& operator()(const int& row, const int& col) const;
	// m(1,2) = 5
	double& operator()(const int& row, const int& col);

	bool operator==(const Matrix& matrix) const;
	bool operator!=(const Matrix& matrix) const;
	Matrix& operator=(const Matrix& matrix);
	Matrix& operator+=(const Matrix& matrix);
	Matrix& operator-=(const Matrix& matrix);
	Matrix& operator*=(const Matrix& matrix);
	Matrix& operator*=(const double& scalar);
	Matrix operator+(const Matrix& matrix) const;
	Matrix operator-(const Matrix& matrix) const;
	Matrix operator-() const; // m1 = -m2
	Matrix operator*(const double& scalar) const;
	Matrix operator*(const Matrix& matrix) const;

	static Matrix createUnit(const int dimension);
	Matrix transpose();
	Matrix inverse() const;
};

Matrix operator*(const double& scalar, const Matrix& matrix);

#endif /* MATRIX_H_ */
